<?php

namespace App\Models\Traits;

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Cache;

trait EventRecordTable
{
    //是否分表，默认false，即不分表
    protected $isSplitTable = true;

    //原表
    public $originTable;

    //表
    public $endTable;

    /**
     * 后缀参数
     * @var string
     */
    protected $suffix = null;

    /**
     * 年参数：2021
     * @var string
     */
    public $year;

    public function init($suffix = null)
    {
        //默认原表
        $this->originTable = $this->table;
        //默认最终表
        $this->endTable = $this->table;

        $this->year = Carbon::now()->format('Y');

        //isSplitTable参数为true时进行分表，否则不分表
        if ($this->isSplitTable) {
            //初始化后缀，未传则默认年分表
            $this->suffix = $suffix ?: $this->year;
        }
        //初始化分表表名并创建
        $this->setSuffix();
    }

    /**
     * 设置表后缀, 如果设置分表后缀，可在service层调用生成自定义后缀表名，
     * 但每次操作表之前都需要调用该方法以保证数据表的准确性
     * @param $suffix
     */
    public function setSuffix($suffix = null)
    {
        //isSplitTable参数为true时进行分表，否则不分表
        if ($this->isSplitTable) {
            //初始化后缀，未传则默认年分表
            $this->suffix = $suffix ?: $this->year;
        }
        if ($this->suffix !== null) {
            //$this->endTable = $this->getTable() . '_' . $suffix;
            $this->endTable = $this->originTable . '_' . $this->suffix;

            //最终表替换模型中声明的表作为分表使用的表
            $this->table = $this->endTable;
        }
        //调用时，创建分表，格式为 table_{$suffix}
        //未传自定义后缀情况下,，默认按年分表格式为：orders_2022
        //无论使用时是否自定义分表名，都会创建默认的分表，除非关闭该调用
        //$this->createTable();
    }

    /**
     * 提供一个静态方法设置表后缀
     * @param string $suffix
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function suffix($suffix = null)
    {
        $instance = new static;
        $instance->setSuffix($suffix);
        return $instance->newQuery();
    }

    /**
     * 创建新的"table_{$suffix}"的模型实例并返回
     * @param array $attributes
     * @param bool $exists
     * @return object $model
     */
    public function newInstance($attributes = [], $exists = false)
    {
        $model = parent::newInstance($attributes, $exists);
        $model->setSuffix($this->suffix);
        return $model;
    }

    /**
     * 创建分表，没有则创建，有则不处理
     */
    protected function createTable()
    {
        $key = 'has_table-' . $this->endTable;
        $end_table = $this->endTable;
        $has_table = Cache::rememberForever($key, function () use ($end_table) {
            return Schema::hasTable($end_table);
        });
        if (!$has_table) {
            info("创建表==========", [$this->endTable]);
            DB::update("create table {$this->endTable} like {$this->originTable}");
        }
    }
}
